package com.hzw.video.decoder

import android.media.*
import android.os.Build
import androidx.annotation.RequiresApi
import com.hzw.video.extractor.AudioExtractor
import com.hzw.video.extractor.IExtractor
import java.nio.ByteBuffer

/**
 *
 * @Author:         HuaZhongWei
 * @CreateDate:     2020/9/16 10:07
 *
 * @Description:
 *
 */
class AudioDecoder(path: String) : BaseDecoder(path) {

    /**采样率*/
    private var sampleRate = -1

    /**声音通道数量*/
    private var channels = 1

    /**PCM采样位数*/
    private var pcmEncodeBit = AudioFormat.ENCODING_PCM_16BIT

    /**音频播放器*/
    private var audioTrack: AudioTrack? = null

    /**音频数据缓存*/
    private var audioOutTempBuf: ShortArray? = null

    override fun check(): Boolean = true

    override fun initExtractor(filePath: String): IExtractor {
        return AudioExtractor(filePath)
    }

    @RequiresApi(Build.VERSION_CODES.N)
    override fun initSpecParams(format: MediaFormat) {
        channels = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT)
        sampleRate = format.getInteger(MediaFormat.KEY_SAMPLE_RATE)
        pcmEncodeBit = if (format.containsKey(MediaFormat.KEY_PCM_ENCODING)) {
            format.getInteger(MediaFormat.KEY_PCM_ENCODING)
        } else {
            AudioFormat.ENCODING_PCM_16BIT
        }
    }

    override fun initRender(): Boolean {
        val channel = if (channels == 1) {
            AudioFormat.CHANNEL_OUT_MONO  //单声道
        } else {
            AudioFormat.CHANNEL_OUT_STEREO  //双声道
        }

        //获取最新缓冲区
        val minBufferSize = AudioTrack.getMinBufferSize(sampleRate, channel, pcmEncodeBit)

        audioOutTempBuf = ShortArray(minBufferSize)

        audioTrack = AudioTrack(
            AudioAttributes.Builder()
                .setLegacyStreamType(AudioManager.STREAM_MUSIC) //播放类型：音乐
                .build(),
            AudioFormat.Builder()
                .setChannelMask(channel)//通道
                .setEncoding(pcmEncodeBit)//采样位数
                .setSampleRate(sampleRate)//采样率
                .build(),
            minBufferSize,//缓冲区大小
            AudioTrack.MODE_STREAM, //播放模式：数据流动态写入，另一种是一次性写入
            AudioManager.AUDIO_SESSION_ID_GENERATE
        )

        audioTrack!!.play()
        return true
    }

    override fun configCodec(mediaCodec: MediaCodec, format: MediaFormat): Boolean {
        mediaCodec.configure(format, null, null, 0)
        return true
    }

    override fun render(byteBuffer: ByteBuffer, bufferInfo: MediaCodec.BufferInfo) {
        if (audioOutTempBuf!!.size < bufferInfo.size / 2) {
            audioOutTempBuf = ShortArray(bufferInfo.size / 2)
        }
        byteBuffer.position(0)
        //把解码数据由ByteBuffer类型转换为ShortBuffer，这时Short数据类型的长度要减半。
        // short 16位， byte 8位
        byteBuffer.asShortBuffer().get(audioOutTempBuf, 0, bufferInfo.size / 2)
        audioTrack!!.write(audioOutTempBuf!!, 0, bufferInfo.size / 2)
    }

    override fun doneDecode() {
        audioTrack?.stop()
        audioTrack?.release()
    }

    override fun pause() {

    }

    override fun goOn() {

    }

    override fun stop() {
        extractor?.stop()
    }

    override fun isDecoding(): Boolean {
        return isRunning
    }

    override fun isSeeking(): Boolean {
        return isRunning
    }

    override fun isStop(): Boolean {
        return isRunning
    }

    override fun getWidth(): Int {
        return videoWidth
    }

    override fun getHeight(): Int {
        return videoHeight
    }

    override fun getRotationAngle(): Int {
        return 0
    }

    override fun getMediaFormat(): MediaFormat? {
        return extractor?.getFormat()
    }

    override fun getTrack(): Int {
        return extractor?.getTrack() ?: 0
    }
}